/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.ac.iie.di.ban.news.server.check;

import static cn.ac.iie.di.ban.news.server.check.CheckDesc.enumToString;
import cn.ac.iie.di.ban.news.server.check.checkers.Base64Checker;
import cn.ac.iie.di.ban.news.server.check.checkers.DomainChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.EmailChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.EnmusChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.IntegerNonZeroRangeChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.IntegerZeroRangeChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.IpChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.LongChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.MD5Checker;
import cn.ac.iie.di.ban.news.server.check.checkers.PhoneChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.PlatInfoChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.QQChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.TimeDelayChecker;
import cn.ac.iie.di.ban.news.server.check.checkers.TimeLaterChecker;
import static cn.ac.iie.di.ban.news.server.handlers.data.DataHandler.getChecker;
import cn.ac.iie.di.ban.news.server.runtime.RuntimeEnv;
import cn.ac.iie.di.ban.news.server.runtime.RuntimeEnvException;
import cn.ac.iie.di.ban.news.server.util.HttpUtils;
import static cn.ac.iie.di.ban.news.server.util.HttpUtils.httpPost;
import cn.ac.iie.di.datadock.rdata.exchange.client.core.REFieldType;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;

/**
 *
 * @author zwlin
 */
public class JsonChecker {

    private static final Logger logger = Logger.getLogger(JsonChecker.class);

    private static final HashMap<CheckDesc.CheckType, Checker> CHECK_MAP;

    private ArrayBlockingQueue<String> configHosts;
    private long configInteval;
    private boolean needHttps;
    private boolean isActivated;
    private Timer updateTimer;

    static {
        CHECK_MAP = new HashMap<>();
        CHECK_MAP.put(CheckDesc.CheckType.Base64, new Base64Checker());
        CHECK_MAP.put(CheckDesc.CheckType.Domain, new DomainChecker());
        CHECK_MAP.put(CheckDesc.CheckType.IntegerNonZeroRange, new IntegerNonZeroRangeChecker());
        CHECK_MAP.put(CheckDesc.CheckType.IntegerZeroRange, new IntegerZeroRangeChecker());
        CHECK_MAP.put(CheckDesc.CheckType.Ip, new IpChecker());
        CHECK_MAP.put(CheckDesc.CheckType.Long, new LongChecker());
        CHECK_MAP.put(CheckDesc.CheckType.MD5, new MD5Checker());
        CHECK_MAP.put(CheckDesc.CheckType.TimeDelay, new TimeDelayChecker());
        CHECK_MAP.put(CheckDesc.CheckType.TimeLater, new TimeLaterChecker());
        CHECK_MAP.put(CheckDesc.CheckType.Email, new EmailChecker());
        CHECK_MAP.put(CheckDesc.CheckType.Phone, new PhoneChecker());
        CHECK_MAP.put(CheckDesc.CheckType.PlatInfo, new PlatInfoChecker());
        CHECK_MAP.put(CheckDesc.CheckType.QQ, new QQChecker());
        CHECK_MAP.put(CheckDesc.CheckType.Enums, new EnmusChecker());

    }

    private static class TypeInfo {

        String type;
        Set<String> required;
        Map<String, CheckDesc[]> checks;
        Map<String, REFieldType> fields;

        public TypeInfo(String type, Set<String> required, Map<String, CheckDesc[]> checks, Map<String, REFieldType> fields) {
            this.type = type;
            this.required = required;
            this.checks = checks;
            this.fields = fields;
        }

        public TypeInfo() {
        }

        @Override
        public String toString() {
//            Map<String, String> content = new HashMap<>();
//            content.put("type", this.type);
////            content.put("checks", this.checks.toString());
//            content.put("required", this.required.toString());
//            content.put("fields", this.fields.toString());
            JSONObject joj = new JSONObject();
            joj.put("type", this.type.toString());
            JSONObject check = new JSONObject();
            for (String name : this.checks.keySet()) {
                JSONArray array = new JSONArray();
                for (CheckDesc d : this.checks.get(name)) {
//                    logger.info(array);
//                    logger.info(d.type);
//                    logger.info(enumToString(d));
                    array.add(enumToString(d));
                }
                check.put(name, array);
            }
            joj.put("checks", check.toString());
            joj.put("required", this.required.toString());
            joj.put("fields", this.fields.toString());
            return "this is json " + joj.toString();
        }
    }

    HashMap<String, TypeInfo> Checkers;

    public JsonChecker(Collection<String> updateHosts, int updateIntervalSecond, boolean needHttps) {
        Checkers = new HashMap<>();
        this.configInteval = updateIntervalSecond;
        this.configHosts = new ArrayBlockingQueue<>(updateHosts.size() + 2, false, updateHosts);
        this.needHttps = needHttps;
        isActivated = false;
        updateTimer = new Timer("JsonCheckerUpdateTimer");
    }

    public void start() {
        updateTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                updateChecker();
            }
        }, 0, configInteval * 1000);
        isActivated = true;
    }

    public void stop() {
        isActivated = false;
        updateTimer.cancel();
    }

    public void updateChecker() {
        try {
            Map<String, Set<JSONObject>> check = new HashMap<>();
            JSONObject[] company = SearchTable("company_group", new JSONObject().toString());
            logger.debug("company_group :" + Arrays.asList(company));
            for (JSONObject cpObj : company) {
                JSONObject[] group = SearchTable("group_channel", "{\"g_id\":\"" + cpObj.getString("g_id") + "\"}");
                logger.debug("group_channel :" + Arrays.asList(group));
                for (JSONObject gObj : group) {
                    JSONObject[] channel = SearchTable("channel", "{\"ch_id\":\"" + gObj.getString("ch_id") + "\"}");
                    logger.debug("channel :" + Arrays.asList(channel));
                    JSONObject[] channel_field = SearchTable("channel_field", "{\"ch_id\":\"" + gObj.getString("ch_id") + "\"}");
                    logger.debug("channel_field :" + Arrays.asList(channel_field));
                    Set<JSONObject> fileds = new HashSet<JSONObject>();
                    for (JSONObject cfObj : channel_field) {
                        JSONObject[] field = SearchTable("field", "{\"f_id\":\"" + cfObj.getString("f_id") + "\"}");
                        logger.debug("field :" + Arrays.asList(field));
                        fileds.add(field[0]);
                    }
                    check.put(cpObj.getString("formal_key") + "_" + cpObj.getString("version") + "_" + channel[0].getString("data_type"), fileds);
                }
            }
            HashMap<String, TypeInfo> map = new HashMap<String, TypeInfo>();
            for (String checkKeyName : check.keySet()) {
                Set<String> required = new HashSet<>();
                Set<JSONObject> jsons = check.get(checkKeyName);
                Map<String, String> srcMap = new HashMap<>();
                Map<String, String> checkMap = new HashMap<>();
                for (JSONObject j : jsons) {
                    if ("no".equalsIgnoreCase(j.getString("nullable"))) {
                        required.add(j.getString("name"));
                    }
                    srcMap.put(j.getString("name"), j.getString("type"));
                    if (null != j.getString("format_check") && !j.getString("format_check").trim().isEmpty() && !"null".equalsIgnoreCase(j.getString("format_check"))) {
                        checkMap.put(j.getString("name"), j.getString("format_check"));
                    }
                }
                map.put(checkKeyName, new TypeInfo(checkKeyName.split("_")[1] + "_" + checkKeyName.split("_")[2], required, getParamAsCheckDescMap(checkMap), getParamAsTypeMap(srcMap)));
            }
            this.Checkers = map;
            logger.info("jsonCheck Checkers: " + Checkers.toString());
        } catch (Exception e) {
            logger.error(e, e);
        }
    }

    public void reg(String key, String version, String type, Set<String> required, Map<String, CheckDesc[]> checks, Map<String, REFieldType> fields) {
        Checkers.put(key, new TypeInfo(version + "_" + type, required, checks, fields));
    }

    //testme
    public CheckResult check(String msg_key, JSONObject rec) {
//        logger.info("==============1" + msg_key + " " + rec.toString());

        if (!Checkers.containsKey(msg_key)) {
            logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-1 " + "msg_version msg_type error.version is:" + msg_key.split("_")[1]);
            return new CheckResult("{\"error_record\":\"msg_version or msg_type error.\"}");
        }

        TypeInfo typeInfo = Checkers.get(msg_key);

        Set<String> required = typeInfo.required;
        Map<String, CheckDesc[]> checks = typeInfo.checks;
        Map<String, REFieldType> fields = typeInfo.fields;
//        logger.info("==============2" + required.toString() + " " + checks.toString() + " " + fields.toString());
        HashMap<String, String> errorMap = new HashMap<>();
        //check fields list
        List<String> unknow = new ArrayList<>();
        for (String key : rec.keySet()) {
            if (!fields.containsKey(key)) {
                unknow.add(key);
            }
        }
        if (!unknow.isEmpty()) {
            logger.error(msg_key + " : " + typeInfo.type + " Not needed fields :" + Arrays.asList(unknow));
            errorMap.put(Arrays.asList(unknow).toString(), "Not needed fields.");
        }

        //check required
        for (String s : required) {
            if (!rec.containsKey(s) || rec.get(s) == null || rec.get(s).toString().trim().isEmpty()) {
                errorMap.put(s, "required but not exist.");
            }
        }

        //check type
        for (String key : rec.keySet()) {
            REFieldType type = fields.get(key);
            //value is null, pass
            if (rec.get(key) == null) {
                continue;
            }
            //not mentioned
            if (type == null) {
                continue;
            }
            //mentioned
            switch (type) {
                case Int:
                    try {
                        rec.getInteger(key);
                    } catch (Exception e) {
                        errorMap.put(key, "type error, need Int.");
                    }
                    break;
                case Long:
                    try {
                        Long.parseLong(rec.getString(key));
                    } catch (Exception e) {
                        errorMap.put(key, "type error, need Long.");
                    }
                    break;
                case String:
//                    try {
//                        if(rec.getString(key).trim().isEmpty()){
//                            throw new Exception();
//                        }
//                    } catch (Exception e) {
//                        errorMap.put(key, "type error,String isEmpty.");
//                    }
                    break;
                case Strings:
                    try {
                        JSONArray array = rec.getJSONArray(key);
                        if (array != null && !array.isEmpty()) {
                            for (int i = 0; i < array.size(); ++i) {
                                array.getString(i);
                            }
                        }
                    } catch (Exception e) {
                        errorMap.put(key, "type error, need string array.");
                    }
                    break;
                default:
                    break;
            }
        }
        //check detail
        for (String key : rec.keySet()) {
            //has error before
            if (errorMap.containsKey(key)) {
                continue;
            }
            //value is null, pass
            if (rec.get(key) == null) {
                continue;
            }
            if (checks.containsKey(key)) {
                CheckDesc[] checkDescs = checks.get(key);
                for (CheckDesc checkDesc : checkDescs) {
                    Object v;
                    switch (fields.get(key)) {
                        case Int:
                            v = rec.getInteger(key);
                            break;
                        case Long:
                            v = rec.getLong(key);
                            break;
                        case String:
                            v = rec.getString(key);
                            break;
                        case Strings:
                            JSONArray a = rec.getJSONArray(key);
                            String[] strs = new String[a.size()];
                            for (int i = 0; i < a.size(); ++i) {
                                strs[i] = a.getString(i);
                            }
                            v = strs;
                            break;
                        default:
                            v = rec.get(key);
                    }
                    if (v == null) {
                        continue;
                    }
                    CheckResult rslt = null;
                    Object param = null;
                    switch (checkDesc.type) {
                        case Base64:
                            if (v instanceof String) {
                            } else if (v instanceof String[]) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Domain:
                            if (v instanceof String) {
                            } else if (v instanceof String[]) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case IntegerNonZeroRange:
                        case IntegerZeroRange:
                            if (v instanceof Long) {
                                param = checkDesc.param;
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Ip:
                            if (v instanceof String) {
                            } else if (v instanceof String[]) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Long:
                            if (v instanceof Integer) {
                                continue;
                            } else if (v instanceof Long) {
                                continue;
                            } else if (v instanceof String) {
                            } else if (v instanceof String[]) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case MD5:
                            if (v instanceof String) {
                                try {
                                    param = rec.getString((String) checkDesc.param);
                                } catch (Exception e) {
                                    rslt = new CheckResult("field type error.detail:"
                                            + ExceptionUtils.getStackTrace(e));
                                }
                            } else if (v instanceof String[]) {
                                try {
                                    JSONArray a = rec.getJSONArray((String) checkDesc.param);
                                    if (v == null || ((String[]) v).length == 0) {
                                        rslt = new CheckResult();
                                    } else if (((String[]) v).length != a.size()) {
                                        rslt = new CheckResult("MD5 field size error.");
                                    } else {
                                        String[] strs = new String[a.size()];
                                        for (int i = 0; i < strs.length; ++i) {
                                            strs[i] = a.getString(i);
                                        }
                                        v = strs;
                                    }
                                } catch (Exception e) {
                                    rslt = new CheckResult("field type error.detail:"
                                            + ExceptionUtils.getStackTrace(e));
                                }
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case TimeDelay:
                            if (v instanceof String) {
                                param = checkDesc.param;
                            } else if (v instanceof String[]) {
                                param = checkDesc.param;
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case TimeLater:
                            if (v instanceof String) {
                                param = rec.get(checkDesc.param);
                            } else if (v instanceof String[]) {
                                param = rec.get(checkDesc.param);
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Email:
                            if (v instanceof String) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Phone:
                            if (v instanceof String) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case PlatInfo:
                            if (v instanceof String) {
                            } else if (v instanceof String[]) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case QQ:
                            if (v instanceof String) {
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        case Enums:
                            if (v instanceof String[]) {
                            } else if (v instanceof String) {
                                param = checkDesc.param;
                            } else {
                                rslt = new CheckResult("field type error.");
                            }
                            break;
                        default:
                            rslt = new CheckResult();
                    }
                    if (rslt == null) {
                        try {
                            Checker checker = CHECK_MAP.get(checkDesc.type);
                            if (v.getClass().isArray()) {
                                String r = "";
                                if (param != null && param.getClass().isArray()) {
                                    for (int i = 0; i < Array.getLength(v); ++i) {
                                        CheckResult result = checker.check(Array.get(v, i), Array.get(param, i));
                                        if (!result.correct) {
                                            if (!r.isEmpty()) {
                                                r += ",";
                                            }
                                            r += "\"" + i + "\":\"" + result.reason + "\"";
                                        }
                                    }
                                } else {
                                    for (int i = 0; i < Array.getLength(v); ++i) {
                                        CheckResult result = checker.check(Array.get(v, i), param);
                                        if (!result.correct) {
                                            if (!r.isEmpty()) {
                                                r += ",";
                                            }
                                            r += "\"" + i + "\":\"" + result.reason + "\"";
                                        }
                                    }
                                }
                                if (r.isEmpty()) {
                                    rslt = new CheckResult();
                                } else {
                                    rslt = new CheckResult("{" + r + "}");
                                }
                            } else {
                                rslt = checker.check(v, param);
                            }
                        } catch (Exception e) {
                            rslt = new CheckResult("unknow check error." + ExceptionUtils.getStackTrace(e));
                        }
                    }
                    if (!rslt.correct) {
                        errorMap.put(key, rslt.reason);
                    }
                }
            }
        }
        if (errorMap.isEmpty()) {
            return new CheckResult();
        } else {
            for (String ekey : errorMap.keySet()) {
                if (errorMap.get(ekey).contains("msg_version msg_type")) {
                    logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-1 " + "msg_version msg_type error.version is:" + msg_key.split("_")[1]);
                } else if (errorMap.get(ekey).contains("Not needed fields")) {
                    logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-2 " + ekey + ":" + " Not needed fields");
                } else if (errorMap.get(ekey).contains("required but not exist")) {
                    logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-3 " + ekey + ":" + errorMap.get(ekey));
                } else if (errorMap.get(ekey).contains("type error")) {
                    logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-4 " + ekey + ":" + errorMap.get(ekey));
                } else {
                    logger.error("insert influx: " + msg_key.split("_")[0] + " " + msg_key.split("_")[2] + " 5-5 " + ekey + ":" + errorMap.get(ekey));
                }
            }
            JSONObject rslt = new JSONObject();
            for (Map.Entry<String, String> entry : errorMap.entrySet()) {
                if (REFieldType.Strings.equals(fields.get(entry.getKey()))) {
                    rslt.put("error_" + entry.getKey(), entry.getValue());
                } else {
                    rslt.put("error_" + entry.getKey(), entry.getValue());
                }
            }
            return new CheckResult(rslt.toJSONString());
        }
    }

    /**
     * 表查询接口
     *
     * @param scope 表名
     * @param condition 查询where条件 json格式
     * @return 查询所得json数组
     * @throws Exception
     */
    public JSONObject[] SearchTable(String scope, String condition) throws Exception {
        JSONObject[] jsons = new JSONObject[0];
        HashMap<String, String> param = new HashMap<>();
        param.put("scope", scope);
        param.put("opration", "search");
        param.put("content", "{}");
        param.put("condition", condition);
        String host = configHosts.poll();
        configHosts.put(host);
        HttpUtils.Result result = httpPost(host, param);
        if (result.statusCode != HttpServletResponse.SC_OK) {
            logger.error("update " + host + " failed because :" + result.reasonPhrase);
        } else {
            JSONObject jsonObj = JSONObject.parseObject(result.content);
            if ("succeeded".equals(jsonObj.getString("status"))) {
                JSONArray array = jsonObj.getJSONArray("data");
                jsons = new JSONObject[array.size()];
                for (int i = 0; i < array.size(); i++) {
                    jsons[i] = array.getJSONObject(i);
                }
            }
        }
        return jsons;
    }

    public static Map<String, REFieldType> getParamAsTypeMap(Map<String, String> srcMap) throws RuntimeEnvException {
        HashMap<String, REFieldType> rtn = new HashMap<>();
        for (Map.Entry<String, String> entry : srcMap.entrySet()) {
            switch (entry.getValue().trim().toLowerCase()) {
                case "int":
                case "integer":
                case "n":
                case "i":
                case "\\d":
                case "int_s":
                    rtn.put(entry.getKey(), REFieldType.Int);
                    break;
                case "long":
                case "l":
                case "ld":
                case "long_s":
                    rtn.put(entry.getKey(), REFieldType.Long);
                    break;
                case "string":
                case "str":
                case "s":
                case "\\s":
                case "string_s":
                    rtn.put(entry.getKey(), REFieldType.String);
                    break;
                case "strings":
                case "string[]":
                case "array<string>":
                case "string_a":
                    rtn.put(entry.getKey(), REFieldType.Strings);
                    break;
                case "struct":
                    rtn.put(entry.getKey(), REFieldType.Struct);
                    break;
                case "structs":
                    rtn.put(entry.getKey(), REFieldType.Structs);
                    break;
            }
        }
        return rtn;
    }

    public static Map<String, CheckDesc[]> getParamAsCheckDescMap(Map<String, String> param) throws RuntimeEnvException {
        HashMap<String, CheckDesc[]> rtn = new HashMap<>();
        for (Map.Entry<String, String> entry : param.entrySet()) {
            CheckDesc[] descs = new CheckDesc[entry.getValue().split("\\,").length];
            for (int i = 0; i < entry.getValue().split(",").length; i++) {
                CheckDesc desc = CheckDesc.parse(entry.getValue().split(",")[i]);
                descs[i] = desc;
            }
            if (descs.length != 0) {
                rtn.put(entry.getKey(), descs);
            }
        }
        return rtn;
    }

    public static void main(String[] args) {
//        String s = "|1246672122487|3017880";
//        System.out.println(s.split("\\|").length);
//        System.out.println(s.substring(2));
//        System.out.println(String.valueOf(Long.MAX_VALUE).length());
//        System.out.println(s.length());
//        System.out.println(Long.valueOf(s));
        String newversion = "{\"POSTIP\":\"aaa=\"}";
        //            + "\"VIDEOURLS\":[\"aHR0cHM6Ly90aW1nc2EuYmFpZHUuY29tL3RpbWc/aW1hZ2UmcXVhbGl0eT04MCZzaXplPWI5OTk5XzEwMDAwJnNlYz0xNTE1NjU5NzU2JmRpPWYyMmRjMzRkMGQ5ZjU0ZTkzMDZjNWI5ZTk2MjE0NzJiJmltZ3R5cGU9anBnJmVyPTEmc3JjPWh0dHAlM0ElMkYlMkZwaWMzNi5waG90b3Bob3RvLmNuJTJGMjAxNTA4MTElMkYwMDA3MDE5ODc4MzQ4MTc4X2IuanBn\",\"aHR0cHM6Ly90aW1nc2EuYmFpZHUuY29tL3RpbWc/aW1hZ2UmcXVhbGl0eT04MCZzaXplPWI5OTk5XzEwMDAwJnNlYz0xNTE1NjU5NzU2JmRpPWYyMmRjMzRkMGQ5ZjU0ZTkzMDZjNWI5ZTk2MjE0NzJiJmltZ3R5cGU9anBnJmVyPTEmc3JjPWh0dHAlM0ElMkYlMkZwaWMzNi5waG90b3Bob3RvLmNuJTJGMjAxNTA4MTElMkYwMDA3MDE5ODc4MzQ4MTc4X2IuanBn\",\"aHR0cHM6Ly90aW1nc2EuYmFpZHUuY29tL3RpbWc/aW1hZ2UmcXVhbGl0eT04MCZzaXplPWI5OTk5XzEwMDAwJnNlYz0xNTE1NjU5NzU2JmRpPWYyMmRjMzRkMGQ5ZjU0ZTkzMDZjNWI5ZTk2MjE0NzJiJmltZ3R5cGU9anBnJmVyPTEmc3JjPWh0dHAlM0ElMkYlMkZwaWMzNi5waG90b3Bob3RvLmNuJTJGMjAxNTA4MTElMkYwMDA3MDE5ODc4MzQ4MTc4X2IuanBn\"],\n"
        //            + "\"POSTIP\":\"842335070@qq.com\",\n"
        //            + "\"REGISTERTIME\":\""
        //            + formatter.format(new Date())
        //            + "\",\n"
        //            + "\"PVNUM\":\"132\",\n"
        //            + "\"UVNUM\":165,\n"
        //            + "\"PHONE\":18888888888,\n"
        //            + "\"QQID\":5644643265,\n"
        List s = new ArrayList<String>();
        s.add("http://192.168.11.95:10250/data/");
        JsonChecker jc = new JsonChecker(s, 1000, true);
        jc.updateChecker();
        CheckResult r = jc.check("25e600657ebacc25fc54076c682d2c48_v1.0_2", JSONObject.parseObject(newversion));
        System.out.println(r.reason);
//        public void reg(String key, String version, String type, Set<String> required, Map<String, CheckDesc[]> checks, Map<String, REFieldType> fields) {
//        Checkers.put(key, new TypeInfo(version + "_" + type, required, checks, fields));
//    }
    }

}
